package com.icc.test.controller;
// https://zhuanlan.zhihu.com/p/624297206?utm_id=0
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName TestController
 * @Description: TODO
 * @Author ICC228979
 * @Date 2024/3/21 13:53
 * @Version 1.0
 */
@RestController
@RequestMapping(path = "/test")
@Slf4j
public class TestController {
    final RestHighLevelClient restHighLevelClient;

    public TestController(RestHighLevelClient restHighLevelClient) {
        this.restHighLevelClient = restHighLevelClient;
    }


    @GetMapping(path = "/page")
    public Object page(Integer pageNum, Integer pageSize, String queryText) throws IOException {
        return esPage("article_detail", pageNum, pageSize, queryText);
    }


    public List<Object> esPage(String indexName, Integer pageNum, Integer pageSize, String queryText) throws IOException {
        List<Object> list = new ArrayList<>();
        // 指定搜索的索引
        SearchRequest searchRequest = new SearchRequest(indexName);
        // 构建了一个查询对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        FuzzyQueryBuilder matchQuery = QueryBuilders.fuzzyQuery("chapterText", queryText);
        // MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("chapterText", queryText);

        // 设置查询条件，这里以match_all查询为例
        searchSourceBuilder.query(matchQuery);
        // 设置需要返回的字段
        String[] includeFields = {}; // 替换为你要查询的字段名
        String[] excludeFields = {"chapterHtml", "chapterText"}; // 替换为你要排除的字段名
        searchSourceBuilder.fetchSource(includeFields, excludeFields);

        // 设置高亮
        searchSourceBuilder.highlighter(new HighlightBuilder()
                .field("chapterText"));


        // 设置排序
        searchSourceBuilder.sort(SortBuilders.fieldSort("articleId").order(SortOrder.ASC));  // 替换为你的排序字段名

        // 计算出记录起始下标
        int from = PageUtil.getEnd(pageNum, pageSize);
        // 设置排序
        searchSourceBuilder.size(pageSize);
        // searchSourceBuilder.from(from);
        searchSourceBuilder.trackTotalHits(true);
        // 设置超时时间
        searchSourceBuilder.timeout(TimeValue.timeValueSeconds(5));
        // 将查询对象设置为 SearchRequest 的源
        searchRequest.source(searchSourceBuilder);


        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        String scrollId = searchResponse.getScrollId();

        System.out.println(scrollId);


        // 从 SearchResponse 中获取搜索结果的数组 SearchHit[] searchHits。
        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        int fetchedHits = hits.length;

        log.info("{}", fetchedHits);
        // 遍历 searchHits 数组，对每一个搜索命中的文档进行处理。在此示例中，使用 getSourceAsString() 方法将文档的源数据以字符串形式打印出来。
        for (SearchHit hit : hits) {
            JSONObject jsonObject = JSONUtil.parseObj(hit.getSourceAsString());
            list.add(jsonObject);
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            highlightFields.forEach((hfK, hfV) -> {
                Text[] fragments = hfV.getFragments();
                if (ArrayUtil.isNotEmpty(fragments)) {
                    jsonObject.set(hfK + "Hf", ArrayUtil.join(fragments, ";"));
                }
            });

        }
        return list;
    }
}
